package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    private WorkService workService;


    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
//        日期
        List<LocalDate> dates=new ArrayList<>();
        List<Double> turnovers=new ArrayList<>();

        while (begin.isBefore(end.plusDays(1))) {
//            插入日期
            dates.add(begin);
//          获取每一天的营业额数据
            LocalDateTime begintime=LocalDateTime.of(begin, LocalTime.MIN);
            LocalDateTime endtime=LocalDateTime.of(begin, LocalTime.MAX);

            Map map=new HashMap();
            map.put("begintime",begintime);
            map.put("endtime",endtime);
            map.put("status",5);
            Double sum = orderMapper.sumByTimeStatus(map);
//            对一天进行统计，如果那一天没有数据，则将营业额设置为0
            if(sum==null){
                sum=0.0;
            }
            turnovers.add(sum);

            begin=begin.plusDays(1);
        }
        String date = StringUtils.join(dates, ",");

//      营业额
        String turnover = StringUtils.join(turnovers, ",");

//        数据放入
        TurnoverReportVO vo=new TurnoverReportVO();
        vo.setDateList(date);
        vo.setTurnoverList(turnover);
        return vo;

    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {

//        统计 时间、新增用户、总用户
        List<LocalDate> dates=new ArrayList<>();
        List<Integer> newUserList=new ArrayList<>();
        List<Integer> totalUserList=new ArrayList<>();

//        新用户是在get_time 在对应区间里面的用户
//        总用户是在endtime时间内的用户

        while (begin.isBefore(end.plusDays(1))) {
            dates.add(begin);
            LocalDateTime begintime=LocalDateTime.of(begin, LocalTime.MIN);
            LocalDateTime endtime=LocalDateTime.of(begin, LocalTime.MAX);

            Map map=new HashMap();
            map.put("begintime",begintime);
            map.put("endtime",endtime);
//            查询每日新用户
            Integer newu= userMapper.newUserList(map);
            if(newu==null){
                newu=0;
            }
            newUserList.add(newu);
//            查询当前日期总用户

            totalUserList.add(newUserList.stream().mapToInt(Integer::intValue).sum());
            begin=begin.plusDays(1);
        }
        String date = StringUtils.join(dates, ",");
        String totalUser= StringUtils.join(totalUserList, ",");
        String newUser = StringUtils.join(newUserList, ",");
        UserReportVO vo=new UserReportVO();
        vo.setDateList(date);
        vo.setNewUserList(newUser);
        vo.setTotalUserList(totalUser);
        return vo;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
//    //日期，以逗号分隔，例如：2022-10-01,2022-10-02,2022-10-03
        List<LocalDate> dates=new ArrayList<>();
//    //每日订单数，以逗号分隔，例如：260,210,215  区间内统计的所有订单
        List<Integer> orderCountList=new ArrayList<>();
//    //每日有效订单数，以逗号分隔，例如：20,21,10  区间内完成的订单
        List<Integer> validOrderCountList=new ArrayList<>();
//    订单总数  endtime之前的所有订单
//    有效订单数  endtime之前的所有完成的订单
//      订单完成率

        while (begin.isBefore(end.plusDays(1))) {
            dates.add(begin);
            LocalDateTime begintime=LocalDateTime.of(begin, LocalTime.MIN);
            LocalDateTime endtime=LocalDateTime.of(begin, LocalTime.MAX);

            Map map=new HashMap();
            map.put("begintime",begintime);
            map.put("endtime",endtime);
//          统计每日订单
            Integer order = orderMapper.countByTimeStatus(map);
            if(order==null){
                order=0;
            }
            orderCountList.add(order);
//          统计每日完成订单
            map.put("status",5);
            Integer vaildorder = orderMapper.countByTimeStatus(map);
            if(vaildorder==null){
                vaildorder=0;
            }
            validOrderCountList.add(vaildorder);
//            订单总数

            begin=begin.plusDays(1);
        }
        String datestr = StringUtils.join(dates, ",");
        String orderCountListstr=StringUtils.join(orderCountList, ",");
        String validOrderCountListstr=StringUtils.join(validOrderCountList, ",");

        OrderReportVO vo=new OrderReportVO();
        vo.setDateList(datestr);
        vo.setOrderCountList(orderCountListstr);
        vo.setValidOrderCountList(validOrderCountListstr);

        int TotalOrderCount = orderCountList.stream().mapToInt(Integer::intValue).sum();
        vo.setTotalOrderCount(TotalOrderCount);

        int ValidOrderCount = validOrderCountList.stream().mapToInt(Integer::intValue).sum();
        vo.setValidOrderCount(ValidOrderCount);

        Double OrderCompletionRate=0.0;
        if(TotalOrderCount!=0){
            OrderCompletionRate=(double) ValidOrderCount / TotalOrderCount;
        }
        vo.setOrderCompletionRate(OrderCompletionRate);

        return vo;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
//        按照时间统计，一个菜品的销量，并且进行排序，只要前十
        LocalDateTime begintime=LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endtime=LocalDateTime.of(end, LocalTime.MAX);

        List<GoodsSalesDTO> dto=orderMapper.top10(begintime,endtime);
        // 提取名称
        List<String> names = dto.stream()
                .map(GoodsSalesDTO::getName) // 使用 getter 方法获取名称
                .collect(Collectors.toList());

        // 提取销量
        List<Integer> numbers = dto.stream()
                .map(GoodsSalesDTO::getNumber) // 使用 getter 方法获取销量
                .collect(Collectors.toList());

        // 将名称和销量转换为逗号分隔的字符串
        String namesString = String.join(", ", names);
        String numbersString = numbers.stream()
                .map(String::valueOf) // 将 Integer 转换为 String
                .collect(Collectors.joining(", "));

        return  SalesTop10ReportVO.builder().
                numberList(numbersString)
                .nameList(namesString)
                .build();
    }

    @Override
    public void export(HttpServletResponse response) {

        InputStream in =this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
//       在内存中创建一个Excel文件
        XSSFWorkbook excel = new XSSFWorkbook(in);
//       在execl中创建一个sheet页，名字是info
        XSSFSheet sheet = excel.getSheet("Sheet1");
//·        上面部分
        BusinessDataVO dataVO = workService.businessData(LocalDate.now(), LocalDate.now().plusDays(-30));

        XSSFRow row = sheet.getRow(3);
        row.getCell(2).setCellValue(dataVO.getTurnover());
        row.getCell(4).setCellValue(dataVO.getOrderCompletionRate());
        row.getCell(6).setCellValue(dataVO.getNewUsers());

        row = sheet.getRow(4);
        row.getCell(2).setCellValue(dataVO.getValidOrderCount());
        row.getCell(4).setCellValue(dataVO.getUnitPrice().toString());

        sheet.getRow(1).getCell(1).setCellValue("时间："+LocalDate.now()+"到"+LocalDate.now().plusDays(-30));

//        下面部分
        for(int i=0;i<30;i++){
            //      放入begin和end得到一天的数据
            LocalDate begin=LocalDate.now().plusDays(i-30);
             dataVO = workService.businessData(begin, begin);

//        创建行对象(行列都是从0开始读入)
            row = sheet.getRow(7+i);
//        先锁定行，再在行的基础上放入数据
            row.getCell(1).setCellValue(String.valueOf(begin));
            row.getCell(2).setCellValue(dataVO.getTurnover());
            row.getCell(3).setCellValue(dataVO.getValidOrderCount());
            row.getCell(4).setCellValue(dataVO.getOrderCompletionRate());
            row.getCell(5).setCellValue(dataVO.getUnitPrice());
            row.getCell(6).setCellValue(dataVO.getNewUsers());
        }

//        将内存中的execl工作簿写入到指定的文件输出流中


            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            in.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}
